<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../tf-event-dashboard/tf-data-coordinator.html">
<link rel="import" href="../tf-event-dashboard/tf-tooltip-coordinator.html">
<link rel="import" href="../tf-event-dashboard/tf-run-selector.html">
<link rel="import" href="../tf-event-dashboard/tf-x-type-selector.html">
<link rel="import" href="../tf-dashboard-common/tf-run-generator.html">
<link rel="import" href="../tf-event-dashboard/tf-color-scale.html">
<link rel="import" href="../tf-dashboard-common/tf-url-generator.html">
<link rel="import" href="../tf-dashboard-common/tf-dashboard-layout.html">
<link rel="import" href="../tf-dashboard-common/dashboard-style.html">
<link rel="import" href="../tf-dashboard-common/warning-style.html">
<link rel="import" href="../tf-categorizer/tf-categorizer.html">
<link rel="import" href="../tf-event-dashboard/tf-chart.html">
<link rel="import" href="../tf-collapsable-pane/tf-collapsable-pane.html">
<link rel="import" href="../iron-collapse/iron-collapse.html">
<link rel="import" href="../paper-icon-button/paper-icon-button.html">
<link rel="import" href="../tf-imports/lodash.html">

<!--
tf-histogram-dashboard is a complete frontend that loads runs from a backend,
and creates chart panes that display data for those runs.

It provides a categorizer, run selector, and x type selector, by which the user
can customize how data is organized and displayed.

Each chart has a button that can toggle whether it is "selected"; selectedRuns
charts are larger.

Organizationally, the #plumbing div contains components that have no concrete
manifestation and just effect data bindings or data loading. The #sidebar contains
shared controls like the tf-categorizer, tf-run-selector, and tf-x-type-selector.
The #center div contains tf-charts embedded inside tf-collapsable-panes.
-->
<dom-module id="tf-histogram-dashboard">
  <template>
    <div id="plumbing">
      <tf-url-generator
        router="[[router]]"
        out-runs-url="{{runsUrl}}"
        out-compressed-histograms-url-generator="{{compressedHistogramsUrlGen}}"
        id="urlGenerator"
      ></tf-url-generator>

      <tf-data-coordinator
        id="dataCoordinator"
        url-generator="[[compressedHistogramsUrlGen]]"
        run-to-tag="[[runToCompressedHistograms]]"
        color-scale="[[colorScale]]"
        out-data-coordinator="{{dataCoordinator}}"
      /></tf-data-coordinator>

      <tf-run-generator
        id="runGenerator"
        url="[[runsUrl]]"
        out-run-to-compressed-histograms="{{runToCompressedHistograms}}"
      /></tf-run-generator>

      <tf-color-scale
        id="colorScale"
        runs="[[_runs]]"
        out-color-scale="{{colorScale}}"
        out-class-scale="{{classScale}}"
      ></tf-color-scale>

      <tf-tooltip-coordinator
        id="tooltipCoordinator"
        out-tooltip-updater="{{tooltipUpdater}}"
        out-tooltip-map="{{tooltipMap}}"
        out-x-value="{{tooltipXValue}}"
        out-closest-run="{{closestRun}}"
      ></tf-tooltip-coordinator>
    </div>

    <tf-dashboard-layout>
      <div class="sidebar">
        <div class="sidebar-section">
          <tf-categorizer
            id="categorizer"
            tags="[[_visibleTags]]"
            categories="{{categories}}"
          ></tf-categorizer>
        </div>
        <div class="sidebar-section">
          <tf-x-type-selector
            id="xTypeSelector"
            out-x-type="{{xType}}"
          ></tf-x-type-selector>
        </div>
        <div class="sidebar-section">
          <tf-run-selector
            id="runSelector"
            runs="[[_runs]]"
            class-scale="[[classScale]]"
            out-selected="{{selectedRuns}}"
            tooltips="[[tooltipMap]]"
            closest-run="[[closestRun]]"
            x-value="[[tooltipXValue]]"
            x-type="[[xType]]"
          ></tf-run-selector>
          </div>
      </div>

      <div class="center">
        <template is="dom-if" if="[[!categories.length]]">
          <div class="warning">
            <p>
              No histogram tags were found.
            </p>
            <p>
              Maybe data hasn't loaded yet, or maybe you need
              to add some <code>tf.histogram_summary</code> ops to your graph, and
              serialize them using the <code>tf.training.summary_io.SummaryWriter</code>.
            </p>
          </div>
        </template>
        <template is="dom-repeat" items="[[categories]]">
          <tf-collapsable-pane name="[[item.name]]" count="[[_count(item.tags, selectedRuns.*, runToCompressedHistograms.*)]]">
            <div class="layout horizontal wrap">
              <template is="dom-repeat" items="[[item.tags]]" as="tag">
                <template is="dom-repeat" items="[[selectedRuns]]" as="run">
                  <template is="dom-if" if="[[_exists(run, tag, runToCompressedHistograms.*)]]">
                    <div class="card">
                      <span class="card-title">[[tag]]</span>
                      <div class="card-content">
                        <tf-chart
                          tag="[[tag]]"
                          type="compressedHistogram"
                          id="chart"
                          selected-runs="[[_array(run)]]"
                          x-type="[[xType]]"
                          data-coordinator="[[dataCoordinator]]"
                          color-scale="[[colorScale]]"
                          on-keyup="toggleSelected"
                          tabindex="2"
                          tooltip-updater="[[tooltipUpdater]]"
                        ></tf-chart>
                        <paper-icon-button
                          class="expand-button"
                          icon="fullscreen"
                          on-tap="toggleSelected"
                        ></paper-icon-button>
                      </div>
                    </div>
                  </template>
                </template>
              </template>
            </div>
          </tf-collapsable-pane>
        </template>
      </div>
    </tf-dashboard-layout>

    <style include="dashboard-style"></style>
    <style include="warning-style"></style>
  </template>

  <script>
    Polymer({
      is: "tf-histogram-dashboard",
      properties: {
        _runs: {
          type: Array,
          computed: "_getRuns(runToCompressedHistograms)",
        },
        _visibleTags: {
          type: Array,
          computed: "_getVisibleTags(selectedRuns.*, runToCompressedHistograms.*)"
        },
        router: {
          type: Object,
          value: TF.Urls.productionRouter(),
        },
      },
      _exists: function(run, tag, runToCompressedHistogramsChange) {
        var runToCompressedHistograms = runToCompressedHistogramsChange.base;
        return runToCompressedHistograms[run].indexOf(tag) !== -1;
      },
      _array: function(x) {
        return [x];
      },
      _count: function(tags, selectedRunsChange, runToCompressedHistogramsChange) {
        var selectedRuns = selectedRunsChange.base;
        var runToCompressedHistograms = runToCompressedHistogramsChange.base;
        var targetTags = {};
        tags.forEach(function(t) {
          targetTags[t] = true;
        });
        var count = 0;
        selectedRuns.forEach(function(r) {
          runToCompressedHistograms[r].forEach(function(t) {
            if (targetTags[t]) {
              count++;
            }
          });
        });
        return count;
      },
      _getRuns: function(runToCompressedHistograms) {
        return _.keys(runToCompressedHistograms);
      },
      _getVisibleTags: function(selectedRunsChange, runToCompressedHistogramsChange) {
        var keys = selectedRunsChange.base;
        var dict = runToCompressedHistogramsChange.base;
        return _.union.apply(null, keys.map(function(k) {return dict[k]}));
      },
      toggleSelected: function(e) {
        var currentTarget = Polymer.dom(e.currentTarget);
        var parentDiv = currentTarget.parentNode.parentNode;
        parentDiv.classList.toggle("selected");
        var chart = currentTarget.previousElementSibling;
        if (chart) {
          chart.redraw();
        }
      },
    });
  </script>
</dom-module>
